package com.andnnl.template;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.hutool.json.JSONUtil;

/**
 * 短信模板管理类
 *
 * @author Kender 匹配企业设定的模板或公共模板，符合模板规则的则免人工审核
 */

public class HfTemplateManager {
    private static HfTemplateManager instance = new HfTemplateManager();
    private static final int MAX_TEMP_LEN = 1000; //模板变量部分最长长度

    private HfTemplateManager() {

    }

    public static HfTemplateManager getInstance() {
        return instance;
    }


    /**
     * 是否在符合模板
     *
     * @param message
     * @return 如匹配其中一个模板返回模板对象
     */
    public void getSmsTemplate(String message) {

//            String templPart[] = eprTemplList.get(i).getPart();
//            boolean isMatch = isMatchTemplate(message, templPart);
//            if (isMatch)
//                return eprTemplList.get(i).getForm();


    }


    /**
     * 是否匹配模板
     *
     * @param msg
     * @param templPart
     * @return
     */
    private static boolean isMatchTemplate(String msg, String templPart[]) {
        int fromIndex = 0;
        int msgLen = msg.length();

        for (int i = 0; i < templPart.length; i++) {
            if (i == 0) {
                if ("".equals(templPart[i]))
                    continue;
                if (msg.startsWith(templPart[i])) {
                    fromIndex = templPart[i].length();
                    continue;
                } else {
                    //大部分的模板与该短信开头就已经不一样，并在这里返回
                    return false;
                }
            }
            if ("".equals(templPart[i]))
                continue;
            //模板以变量结尾，判断null即可
            if (templPart[i] == null) {
                int tempLen = msgLen - fromIndex;  //变量部分字符长度
//                System.out.println((i)+" 最后变量len "+tempLen  +" 变量值："+msg.substring(fromIndex,msgLen));
                if (tempLen > MAX_TEMP_LEN) {
                    //超过变量长度允许最大值，视为不符合模板
                    return false;
                }
                return true;//符合模板
            }
            //System.out.println("fromIndex:"+fromIndex);
            int pos = msg.indexOf(templPart[i], fromIndex);
            //System.out.println("pos:"+pos);

            if (pos < 0) {
                //不匹配，不符合模板
                return false;
            } else {
                int tempLen = pos - fromIndex;  //变量部分字符长度
//                System.out.println((i)+"  变量len "+tempLen +" 变量值："+msg.substring(fromIndex,pos));
                if (tempLen > MAX_TEMP_LEN) {
                    //超过变量长度允许最大值，视为不符合模板
                    return false;
                }
                fromIndex = pos + templPart[i].length();
            }
        }
        //最后判断最后的开始索引为消息长度为匹配成功
        if(msgLen==fromIndex)
            return true;
        return false;
    }



    /**
     * 是否匹配模板
     *
     * @param msg
     * @param templPart
     * @return
     */
    private static List<Map<String,String>> getValueMap(String msg, String templPart[],List<String> paramList) {
        List<Map<String,String>> resultList = new ArrayList<>();
        
        int fromIndex = 0;
        int msgLen = msg.length();

        for (int i = 0; i < templPart.length; i++) {
            if (i == 0) {
                if ("".equals(templPart[i]))
                    continue;
                if (msg.startsWith(templPart[i])) {
                    fromIndex = templPart[i].length();
                    continue;
                } else {
                    //大部分的模板与该短信开头就已经不一样，并在这里返回
                    return null;
                }
            }
            if ("".equals(templPart[i]))
                continue;
            //模板以变量结尾，判断null即可
            if (templPart[i] == null) {
                int tempLen = msgLen - fromIndex;  //变量部分字符长度
//                System.out.println((i)+" 最后变量len "+tempLen  +" 变量值："+msg.substring(fromIndex,msgLen));
                Map<String,String> map = Collections.singletonMap(paramList.get(i-1), msg.substring(fromIndex, msgLen));
                resultList.add(map);
                if (tempLen > MAX_TEMP_LEN) {
                    //超过变量长度允许最大值，视为不符合模板
                    return null;
                }
                return resultList;
            }
            //System.out.println("fromIndex:"+fromIndex);
            int pos = msg.indexOf(templPart[i], fromIndex);
            //System.out.println("pos:"+pos);

            if (pos < 0) {
                //不匹配，不符合模板
                return null;
            } else {
                int tempLen = pos - fromIndex;  //变量部分字符长度
//                System.out.println((i)+"  变量len "+tempLen +" 变量值："+msg.substring(fromIndex,pos));
                Map<String,String> map = Collections.singletonMap(paramList.get(i-1), msg.substring(fromIndex, pos));
                resultList.add(map);
                if (tempLen > MAX_TEMP_LEN) {
                    //超过变量长度允许最大值，视为不符合模板
                    return null;
                }
                fromIndex = pos + templPart[i].length();
            }
        }
        //最后判断最后的开始索引为消息长度为匹配成功
        if(msgLen==fromIndex){
            return resultList;
        }
        return null;
    }

    private static String[] getPartArr(String str2) {
        String part[] = str2.split("\\$\\{\\w+\\}");
        if (!str2.endsWith(part[part.length - 1])) {
            String[] partTemp = new String[part.length + 1];
            for (int i = 0; i < part.length; i++) {
                partTemp[i] = part[i];
            }
            partTemp[part.length] = null;//模板最后一个是变量，设置为null做为标记
            part = partTemp;
        }
        return part;
    }

    /**
     * 返回变量名称列表
     * @param str String str="${wasdf}您好，asdf2312：${wasdf2}，谢谢配合asdf，谢谢配合。${wasdf3}";
     * @return  [wasdf, wasdf2, wasdf3]
     */
    private static List<String> getParamList(String str) {
        Pattern compile = Pattern.compile("\\$\\{\\w+\\}");
        Matcher m = compile.matcher(str);
        List<String> list=new ArrayList<>();
        while (m.find()) {
            String param = m.group();
            String paramName = param.substring(2, param.length() - 1);
//            System.out.println("param:"+param+" "+ paramName);
//            m.appendReplacement(sb, value == null ? "" : value.toString());
            list.add(paramName);
        }
//        return list.toArray(new String[list.size()]);
        return list;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        List<String> list = Arrays.asList(
                "${wasdf}您好，asdf2312：${wasdf2}${wasdf4}，谢谢配合asdf，谢谢配合。${wasdf3}",
                "${wasdf}您好，asdf2312：${wasdf2}，谢谢配合asdf，谢谢配合。",
                "您好，asdf2312：${wasdf2}，谢谢配合asdf，谢谢配合。"
        );

        List<String> matchList = Arrays.asList(
                "22222wasdf222您好，asdf2312：wasdf221221，谢谢配合asdf，谢谢配合。2222",
                "22222wasdf222您好，asdf2312：wasdf221221，谢谢配合asdf，谢谢配合。",
                "您好，asdf2312：wasdf2，谢谢配合asdf，谢谢配合。",
                "您好，asdf2312：，谢谢配合asdf，谢谢配合。",
                "ddddddd"
        );
        for (int i = 0; i < list.size(); i++) {
            String str =list.get(i);
//            String content =matchList.get(i);

            String[] part = getPartArr(str);
            System.out.println("part:"+JSONUtil.toJsonStr(part));
            List<String> paramList = getParamList(str);
//            System.out.println(paramList);
            
            System.out.println("template:"+str);

            for (String content : matchList) {
                // System.out.println(isMatchTemplate(content,part) +" content:"+content);
                System.out.println("content:"+content);
                System.out.println(getValueMap(content,part,paramList));//获匹配模板的取值
                System.out.println();
            }
            System.out.println("***************************");
        }
        
        
        Pattern compile = Pattern.compile("\\$\\{\\w+\\}");
        String str="${wasdf}您好，asdf2312：${wasdf2}${wasdf3}，谢谢配合asdf，谢谢配合。${wasdf3}";
        Matcher m = compile.matcher(str);
//        System.out.println(m.());
        while (m.find()) {
            String param = m.group();
            System.out.println("param:"+param+" "+param.substring(2, param.length() - 1));
//            m.appendReplacement(sb, value == null ? "" : value.toString());
        }
////
//        long t1 = System.currentTimeMillis();
//        TemplateManager m = new TemplateManager();
//
//        boolean isMatch = m.isMatchTemplate(msg, templPart1);
//
//        System.out.println("isMatch=" + isMatch);
//        long t2 = System.currentTimeMillis();
//        System.out.println("isMatch time=" + (t2 - t1) + "ms");
    }


}
